package com.yangfan.screenshot.utils;

import android.content.Context;
import android.graphics.Bitmap;
import android.media.Image;
import android.media.ImageReader;
import android.os.AsyncTask;

import androidx.annotation.NonNull;

import com.yangfan.screenshot.log.LogUtil;

import java.nio.ByteBuffer;
import java.util.Arrays;

/**
 * @author : yangfan
 * @date : 2022/12/9-16:39
 * desc   : image转bitmap，并保存
 */
public final class ImageUtil {

    private final String TAG = ImageUtil.class.getSimpleName();
    private Context mContext;
    private ImageReader imageReader;
    private ImageListener mImageListener;

    /**
     * 重试取imageReader图片次数
     */
    private int retry;

    public interface ImageListener {
        /**
         * 在错误
         */
        void onError();

        /**
         * 一张截图完成
         *
         * @param bitmap 位图
         */
        void onLongScreenshot(@NonNull Bitmap bitmap);
    }

    public ImageUtil(@NonNull Context context, @NonNull ImageReader imageReader, @NonNull ImageListener imageListener) {
        this.imageReader = imageReader;
        this.mImageListener = imageListener;
        mContext = context;
    }

    private final class ImageAsyncTask extends AsyncTask<Image, Bitmap, Boolean> {

        public ImageAsyncTask() {
        }

        @Override
        public void onProgressUpdate(@NonNull Bitmap... bitmapArr) {
            super.onProgressUpdate(Arrays.copyOf(bitmapArr, bitmapArr.length));
            LogUtil.d(TAG,"onProgressUpdate bitmapArr size = " + bitmapArr.length + ";mImageListener = " + mImageListener);
            if (bitmapArr[0] != null) {
                if (mImageListener != null) {
                    Bitmap bitmap2 = bitmapArr[0];
                    mImageListener.onLongScreenshot(bitmap2);
                }
            } else {
                if (mImageListener != null) {
                    mImageListener.onError();
                }
            }
        }

        @Override
        public void onPostExecute(Boolean bool) {
            super.onPostExecute(bool);
            LogUtil.d(TAG,"onPostExecute bool = " + bool);
        }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            String path = FileUtil.instance.getSavePath(mContext);
            LogUtil.d(TAG,"path = " + path);
            FileUtil.instance.mkdirs(path);
        }

        @Override
        @NonNull
        public Boolean doInBackground(@NonNull Image... imageArr) {
            boolean flag = true;
            try {
                if (imageArr.length == 0) {
                    return false;
                }
                Image image = imageArr[0];
                int width = image.getWidth();
                int height = image.getHeight();
                Image.Plane[] planes = image.getPlanes();
                ByteBuffer buffer = planes[0].getBuffer();
                int pixelStride = planes[0].getPixelStride();
                Bitmap createBitmap = Bitmap.createBitmap(((planes[0].getRowStride() - (pixelStride * width)) / pixelStride) + width, height, Bitmap.Config.ARGB_8888);
                createBitmap.copyPixelsFromBuffer(buffer);
                Bitmap createBitmap2 = Bitmap.createBitmap(createBitmap, 0, 0, width, height);
                image.close();
                publishProgress(createBitmap2);
            } catch (Exception e) {
                e.printStackTrace();
                flag = false;
            }

            return flag;
        }
    }


    /**
     * 截图
     *
     */
    public final void capture() {
        Image image = acquireLatestImage();
        if (image == null) {
            if (mImageListener != null) {
                mImageListener.onError();
            }
            return;
        }
        new ImageAsyncTask().execute(image);
    }

    private Image acquireLatestImage() {
        int i;
        Image acquireLatestImage = imageReader.acquireLatestImage();
        LogUtil.d(TAG,"acquireLatestImage = " + acquireLatestImage);
        if (acquireLatestImage == null && (i = this.retry) < 3) {
            this.retry = i + 1;
            return acquireLatestImage();
        } else if (this.retry >= 3) {
            this.retry = 0;
            return null;
        } else {
            this.retry = 0;
            return acquireLatestImage;
        }
    }

}
